// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.globalObjects;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import se.krka.kahlua.vm.KahluaTable;
import zombie.Lua.LuaEventManager;
import zombie.Lua.LuaManager;
import zombie.characters.IsoPlayer;
import zombie.core.BoxedStaticValues;
import zombie.core.Core;
import zombie.core.logger.ExceptionLogger;
import zombie.debug.DebugLog;
import zombie.iso.IsoObject;
import zombie.iso.SliceY;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.TableNetworkUtils;

public final class SGlobalObjects {
    protected static final ArrayList<SGlobalObjectSystem> systems = new ArrayList();

    public static void noise(String message) {
        if (Core.bDebug) {
            DebugLog.log("SGlobalObjects: " + message);
        }
    }

    public static SGlobalObjectSystem registerSystem(String name) {
        SGlobalObjectSystem sGlobalObjectSystem = getSystemByName(name);
        if (sGlobalObjectSystem == null) {
            sGlobalObjectSystem = newSystem(name);
            sGlobalObjectSystem.load();
        }

        return sGlobalObjectSystem;
    }

    public static SGlobalObjectSystem newSystem(String name) throws IllegalStateException {
        if (getSystemByName(name) != null) {
            throw new IllegalStateException("system with that name already exists");
        } else {
            noise("newSystem " + name);
            SGlobalObjectSystem sGlobalObjectSystem = new SGlobalObjectSystem(name);
            systems.add(sGlobalObjectSystem);
            return sGlobalObjectSystem;
        }
    }

    public static int getSystemCount() {
        return systems.size();
    }

    public static SGlobalObjectSystem getSystemByIndex(int index) {
        return index >= 0 && index < systems.size() ? (SGlobalObjectSystem)systems.get(index) : null;
    }

    public static SGlobalObjectSystem getSystemByName(String name) {
        for (int _int = 0; _int < systems.size(); _int++) {
            SGlobalObjectSystem sGlobalObjectSystem = (SGlobalObjectSystem)systems.get(_int);
            if (sGlobalObjectSystem.name.equals(name)) {
                return sGlobalObjectSystem;
            }
        }

        return null;
    }

    public static void update() {
        for (int _int = 0; _int < systems.size(); _int++) {
            SGlobalObjectSystem sGlobalObjectSystem = (SGlobalObjectSystem)systems.get(_int);
            sGlobalObjectSystem.update();
        }
    }

    public static void chunkLoaded(int wx, int wy) {
        for (int _int = 0; _int < systems.size(); _int++) {
            SGlobalObjectSystem sGlobalObjectSystem = (SGlobalObjectSystem)systems.get(_int);
            sGlobalObjectSystem.chunkLoaded(wx, wy);
        }
    }

    public static void initSystems() {
        if (!GameClient.bClient) {
            LuaEventManager.triggerEvent("OnSGlobalObjectSystemInit");
            if (!GameServer.bServer) {
                try {
                    synchronized (SliceY.SliceBufferLock) {
                        SliceY.SliceBuffer.clear();
                        saveInitialStateForClient(SliceY.SliceBuffer);
                        SliceY.SliceBuffer.flip();
                        CGlobalObjects.loadInitialState(SliceY.SliceBuffer);
                    }
                } catch (Throwable throwable) {
                    ExceptionLogger.logException(throwable);
                }
            }
        }
    }

    public static void saveInitialStateForClient(ByteBuffer bb) throws IOException {
        bb.put((byte)systems.size());

        for (int int0 = 0; int0 < systems.size(); int0++) {
            SGlobalObjectSystem sGlobalObjectSystem = (SGlobalObjectSystem)systems.get(int0);
            zombie.GameWindow.WriteStringUTF(bb, sGlobalObjectSystem.name);
            KahluaTable kahluaTable0 = sGlobalObjectSystem.getInitialStateForClient();
            if (kahluaTable0 == null) {
                kahluaTable0 = LuaManager.platform.newTable();
            }

            KahluaTable kahluaTable1 = LuaManager.platform.newTable();
            kahluaTable0.rawset("_objects", kahluaTable1);

            for (int int1 = 0; int1 < sGlobalObjectSystem.getObjectCount(); int1++) {
                GlobalObject globalObject = sGlobalObjectSystem.getObjectByIndex(int1);
                KahluaTable kahluaTable2 = LuaManager.platform.newTable();
                kahluaTable2.rawset("x", BoxedStaticValues.toDouble((double)globalObject.getX()));
                kahluaTable2.rawset("y", BoxedStaticValues.toDouble((double)globalObject.getY()));
                kahluaTable2.rawset("z", BoxedStaticValues.toDouble((double)globalObject.getZ()));

                for (String string : sGlobalObjectSystem.objectSyncKeys) {
                    kahluaTable2.rawset(string, globalObject.getModData().rawget(string));
                }

                kahluaTable1.rawset(int1 + 1, kahluaTable2);
            }

            if (kahluaTable0 != null && !kahluaTable0.isEmpty()) {
                bb.put((byte)1);
                TableNetworkUtils.save(kahluaTable0, bb);
            } else {
                bb.put((byte)0);
            }
        }
    }

    public static boolean receiveClientCommand(String string1, String string0, IsoPlayer isoPlayer, KahluaTable kahluaTable) {
        noise("receiveClientCommand " + string1 + " " + string0 + " OnlineID=" + isoPlayer.getOnlineID());
        SGlobalObjectSystem sGlobalObjectSystem = getSystemByName(string1);
        if (sGlobalObjectSystem == null) {
            throw new IllegalStateException("system '" + string1 + "' not found");
        } else {
            sGlobalObjectSystem.receiveClientCommand(string0, isoPlayer, kahluaTable);
            return true;
        }
    }

    public static void load() {
    }

    public static void save() {
        for (int _int = 0; _int < systems.size(); _int++) {
            SGlobalObjectSystem sGlobalObjectSystem = (SGlobalObjectSystem)systems.get(_int);
            sGlobalObjectSystem.save();
        }
    }

    public static void OnIsoObjectChangedItself(String systemName, IsoObject isoObject) {
        if (!GameClient.bClient) {
            SGlobalObjectSystem sGlobalObjectSystem = getSystemByName(systemName);
            if (sGlobalObjectSystem != null) {
                sGlobalObjectSystem.OnIsoObjectChangedItself(isoObject);
            }
        }
    }

    public static void Reset() {
        for (int _int = 0; _int < systems.size(); _int++) {
            SGlobalObjectSystem sGlobalObjectSystem = (SGlobalObjectSystem)systems.get(_int);
            sGlobalObjectSystem.Reset();
        }

        systems.clear();
        GlobalObjectLookup.Reset();
    }
}
